﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Markup;

namespace BadHabit.Factory.Controls {

    /// <summary>
    /// Interaction logic for ProposalPanel.xaml
    /// </summary>
    public partial class ProposalPanel : GenericPanel {

        public ProposalPanel() {
            InitializeComponent();
        }

        private Data.ProjectDataSet.ProposalRow SelectedProposal {
            get {
                if (proposalListBox == null)
                    return null;
                return Helper.GetRowFromRowView<Data.ProjectDataSet.ProposalRow>(proposalListBox.SelectedItem);

                
            }
        }




        

        private bool CanEditProposal {
            get {
                if (SelectedProposal == null)
                    return false;

                if (SelectedProposal.Status == (short)ProposalStatus.PROPOSAL_APPROVED
                    || SelectedProposal.Status == (short)ProposalStatus.PROPOSAL_REJECTED)
                    return false;

                return true;
                    
            }
        }

        private void EnableDiseableEdit() {            
            if (!CanEditProposal)
                proposalDetailPanel.IsEnabled = false;
            else
                proposalDetailPanel.IsEnabled = true;            
        }

        private void GenericPanel_Loaded(object sender, RoutedEventArgs e) {            
            ShowHideNoProposalMessage();
            SetInitialFocus();
        }

        private void ShowHideNoProposalMessage() {
            if (DataContextAsProjectDataSet != null && DataContextAsProjectDataSet.Proposal.Count == 0) {
                noProposalPanel.Visibility = Visibility.Visible;
                proposalGrid.Visibility = Visibility.Hidden;
            } else {
                noProposalPanel.Visibility = Visibility.Hidden;
                proposalGrid.Visibility = Visibility.Visible;
            }
        }

        private void GenericPanel_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) {
            ShowHideProposalListBox();
            ShowHideNoProposalMessage();
            
            
        }

        private void ShowHideProposalListBox() {
            // if has only one proposal, hide the list box panel
            if (DataContextAsProjectDataSet.Proposal.Count <= 1)
                proposalListBoxBorder.Visibility = Visibility.Collapsed;
            else
                proposalListBoxBorder.Visibility = Visibility.Visible;
        }


        public void ExportProposal() {

            PreviewProposal();

            System.Windows.Forms.SaveFileDialog saveDialog = new System.Windows.Forms.SaveFileDialog();
            saveDialog.FileName = Project.ClientName + " - " + Project.ProjectName + Properties.Resources._Proposal_xps;
            saveDialog.Filter = "XPS File|*.xps";

            System.Windows.Forms.DialogResult d = saveDialog.ShowDialog();
            if (d == System.Windows.Forms.DialogResult.Cancel)
                return;

            Client.FactoryMainWindow.IsWaiting = true;
            BadHabit.XPSTools.XPSHelper.FlowDocumentToXps(flowDocumentViewer.Document, saveDialog.FileName, null, BadHabit.XPSTools.XPSHelper.XPSWriteMode.Overwrite);            
            Client.FactoryMainWindow.IsWaiting = false;
                       


        }

        private string ReadProposalXAML() {
            string template = proposalTemplateComboBox.SelectedItem.ToString();            
            try {
                return Client.Service.GenerateProposalXAML(
                    Client.ConvertToProxyProjectDataSet(DataContextAsProjectDataSet),
                    SelectedProposal.ProposalUId,
                    template);
            } catch (Exception ex) {
                Windows.Error.ShowError(ex, Properties.Resources.COULD_NOT_PREVIEW_PROPOSAL);
                return null;
            }

        }
        

        /// <summary>
        /// Preview the proposal.
        /// </summary>
        public void PreviewProposal() {

            if (Project == null)
                return;

            previewBorder.Visibility = Visibility.Visible;

            
            string flowDocumentXAML;            
            flowDocumentXAML = ReadProposalXAML();
            if (flowDocumentXAML == null)
                return;
            

            System.IO.MemoryStream stream = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(flowDocumentXAML));

            try {
                FlowDocument document = (FlowDocument)XamlReader.Load(stream);
                flowDocumentViewer.Document = document;
            } catch (Exception ex) {
                Windows.Error.ShowError(ex, Properties.Resources.COULD_NOT_RENDER_PROPOSAL);
                return;
            }
        }
        
                
        
        private void addNewClause_Click(object sender, RoutedEventArgs e) {
            short order = 0;
            object o = DataContextAsProjectDataSet.ProposalObservation.Compute("MAX(Order)","");
            if (o != null)
                short.TryParse(o.ToString(), out order);
            order++;

            DataContextAsProjectDataSet.ProposalObservation.AddProposalObservationRow(
                SelectedProposal,
                Properties.Resources.New_clause,
                "",
                Guid.NewGuid().ToString().ToLower(),
                order);
        }

        private void remove_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
            Data.ProjectDataSet.ProposalObservationRow observation = Helper.GetRowFromRowView<Data.ProjectDataSet.ProposalObservationRow>(observationListBox.SelectedItem);
            if (observation == null)
                return;
            observation.Delete();
        }

        private void AddProposal() {
            
            Data.ProjectDataSet dsProjectWithNewProposal = new BadHabit.Factory.Data.ProjectDataSet();
            try {
                dsProjectWithNewProposal.Merge(Client.Service.RetriveProposalTemplate(DataContextAsProjectDataSet.Project[0].Category));
            } catch (Exception ex) {
                Windows.Error.ShowError(ex, Properties.Resources.COULD_NOT_READ_PROPOSAL);
                return;
            }

            if (dsProjectWithNewProposal.Proposal.Count == 0)
                return;

            Data.ProjectDataSet.ProposalRow proposal = dsProjectWithNewProposal.Proposal[0];

            short proposalNumber = (short) (DataContextAsProjectDataSet.Proposal.Count + 1);

            if (proposalNumber == 1)
                proposal.ProposalName = Properties.Resources.Proposal;
            else
                proposal.ProposalName = Properties.Resources.Proposal + " " + (proposalNumber - 1);

            proposal.ProposalNumber = proposalNumber;
            proposal.ProjectUId = DataContextAsProjectDataSet.Project[0].ProjectUId;
            proposal.Details = DataContextAsProjectDataSet.Project[0].Description;
            proposal.StartDate = DataContextAsProjectDataSet.Project[0].EstimatedStartDate;
            proposal.EndDate = DataContextAsProjectDataSet.Project[0].EstimatedEndDate;
            proposal.SalePrice = 0;
            proposal.ScopePrice = 0;
            proposal.FixedCostPrice = 0;
            proposal.UseDiscount = true;
            proposal.Discount = 0;
            proposal.CreateDate = DateTime.Now;
            proposal.Status = (short)ProposalStatus.NO_PROPOSAL;
            proposal.TemplateName = "default.xslt";


            DataContextAsProjectDataSet.Merge(dsProjectWithNewProposal);

            // if is a proposal plan, auto select all backlogitems at proposal
            if (DataContextAsProjectDataSet.Project[0].Baseline == 0)
                SelectAllItemsAtProposal(proposal.ProposalUId);

            

            ShowHideProposalListBox();
            proposalListBox.Items.MoveCurrentToLast();

            ShowHideNoProposalMessage();
            
        }

        private void SelectAllItemsAtProposal(string proposalUId) {
            DataContextAsProjectDataSet.Project[0].MarkVisibleBacklogItemsForProposal(proposalUId);
            foreach (System.Data.DataRow item in DataContextAsProjectDataSet.VisibleBacklogItem.Rows) {
                item["IsAtProposal"] = true;
            }
        }

        
        
        private void RejectProposal_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            e.CanExecute = CanEditProposal;            
        }

        
        private void RejectProposal_Executed(object sender, ExecutedRoutedEventArgs e) {

            if (SelectedProposal.IsRejectReasonNull())
                return;

            short beforeStatus = SelectedProposal.Status;
            SelectedProposal.Status = (short)ProposalStatus.PROPOSAL_REJECTED;
            
            MessageBoxResult d = Windows.Error.ShowDialog(
                Properties.Resources.Confirm_reject_proposal, Properties.Resources.Reject_Proposal, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
            if (d == MessageBoxResult.No) {
                SelectedProposal.Status = beforeStatus;
                SelectedProposal.SetRejectReasonNull();
                return;
            }

            string msg = null;
            FactoryService.ProjectDataSet savedProject = null;
            try {
                savedProject = Client.Service.RejectProposal(Client.ConvertToProxyProjectDataSet(DataContextAsProjectDataSet), SelectedProposal.ProposalUId, out msg);
            } catch (Exception ex) {
                Windows.Error.ShowError(ex, Properties.Resources.COULD_NOT_REJECT_PROPOSAL);
            }
            if (msg != null) {
                Windows.Error.ShowDialog(msg, Properties.Resources.Reject_Proposal, MessageBoxButton.OK, MessageBoxImage.Exclamation, MessageBoxResult.OK);
                return;
            }

            if (savedProject != null) {
                DataContextAsProjectDataSet.Merge(savedProject);
                if (savedProject.Project.Count > 0)
                    Client.UpdateSelectedProject(savedProject.Project[0]);
            }

            DataContextAsProjectDataSet.AcceptChanges();          
            
        }

        private void ApproveProposal_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            e.CanExecute = CanEditProposal;
        }


        private void ApproveProposal_Executed(object sender, ExecutedRoutedEventArgs e) {
            
            MessageBoxResult d = Windows.Error.ShowDialog(Properties.Resources.Confirm_approve_proposal, Properties.Resources.Approve_Proposal,
                MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
            if (d == MessageBoxResult.No)
                return;

            string msg = null;
            FactoryService.ProjectDataSet savedProject = null;
            try {
                savedProject = Client.Service.ApproveProposal(Client.ConvertToProxyProjectDataSet(DataContextAsProjectDataSet), SelectedProposal.ProposalUId, out msg);                
            } catch (Exception ex) {
                Windows.Error.ShowError(ex, Properties.Resources.COULD_NOT_APPROVE_PROPOSAL);            
            }

            if (msg != null) {
                Windows.Error.ShowDialog(msg, Properties.Resources.Approve_Proposal, MessageBoxButton.OK, MessageBoxImage.Exclamation, MessageBoxResult.OK);
                return;
            }

            if (savedProject != null) {
                DataContextAsProjectDataSet.Merge(savedProject);
                Client.UpdateSelectedProject(savedProject.Project[0]);
            }

            DataContextAsProjectDataSet.AcceptChanges();          

        }

        private void EditProposalRoles_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            e.CanExecute = CanEditProposal;
        }


        private void EditProposalRoles_Executed(object sender, ExecutedRoutedEventArgs e) {
            Client.ShowEditRoleWindow(DataContextAsProjectDataSet, true);            
        }

        private void PrintProposal_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            if (SelectedProposal == null) {
                e.CanExecute = false;
                return;
            }

            e.CanExecute = true;
        }

        private void PrintProposal_Executed(object sender, ExecutedRoutedEventArgs e) {
            PreviewProposal();
            flowDocumentViewer.Print();
        }


        private void PreviewProposal_CanExecute(object sender, CanExecuteRoutedEventArgs e) {            
            if (SelectedProposal == null) {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void PreviewProposal_Executed(object sender, ExecutedRoutedEventArgs e) {
            PreviewProposal();
        }

        private void ExportProposal_Executed(object sender, ExecutedRoutedEventArgs e) {
            ExportProposal();
        }

        private void AddProposal_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            if (DataContextAsProjectDataSet == null) {
                e.CanExecute = false;
                return;
            }                
            if (DataContextAsProjectDataSet.Project[0].Status==(short)ProjectStatus.PROJECT_CANCELED
                || DataContextAsProjectDataSet.Project[0].Status == (short)ProjectStatus.PROJECT_DONE) {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void AddProposal_Executed(object sender, ExecutedRoutedEventArgs e) {
            AddProposal();
        }

     

        private void proposalListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {                                               
            EnableDiseableEdit();
            SetInitialFocus();
        }

        private void SetInitialFocus() {

            if (noProposalPanel.Visibility == Visibility.Visible) {
                noProposalPanel.Focus();
                return;
            }

            if (salePriceTextBox.IsEnabled) {
                salePriceTextBox.Focus();
                return;
            }
            
            proposalGrid.Focus();
        }

        private void changeSelectedItems_Click(object sender, RoutedEventArgs e) {
            Windows.ProposalItemSelection w = new BadHabit.Factory.Windows.ProposalItemSelection(SelectedProposal.ProposalUId);
            w.DataContext = this.DataContext;
            w.ShowDialog();
        }

        private void changeFixedCosts_Click(object sender, RoutedEventArgs e) {
            Windows.EditFixedCosts w = new BadHabit.Factory.Windows.EditFixedCosts(SelectedProposal.ProposalUId);
            w.DataContext = this.DataContext;
            w.ShowDialog();

            SelectedProposal.UpdateCalculatedCosts();
            SelectedProposal.UpdateSalePrice();
        }

        
        private void rejectButton_SubmenuClosed(object sender, RoutedEventArgs e) {
            if (SelectedProposal.Status != (short)ProposalStatus.PROPOSAL_REJECTED)
                SelectedProposal.SetRejectReasonNull();
        }

    }
}
